package com.lyw.utils;

import com.lyw.constants.CommonConstants;
import com.lyw.enums.DuplicateEnum;
import com.lyw.factory.TimerTaskFactory;

import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.lang.ref.Reference;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

public class MouseAndKeyEventUtil {

  public static final int STRAIGHT_LINE = 1;

  private static final int[] keyboardContainer = new int[0xFF58];

  public static final PointerInfo pointerInfo = MouseInfo.getPointerInfo();

  public static final AtomicBoolean whetherDoubleClick = new AtomicBoolean(false);
  public static final AtomicInteger whetherClickKeyboard = new AtomicInteger(-1);
  public static final boolean isTrue = false;
  public static Robot robotTool;
  public static TimerTaskFactory taskFactory;

  private MouseAndKeyEventUtil() {
  }

  public static void prepareMouseAndKeyboardTool(Robot robot, TimerTaskFactory taskFactory1) {
    robotTool = robot;
    taskFactory = taskFactory1;
  }

  public static void randomMoveMouse(Robot robot, int x, int y, int delay) {
    Point location = MouseInfo.getPointerInfo().getLocation();
    int startX = Integer.parseInt(String.valueOf(location.getX()));
    int startY = Integer.parseInt(String.valueOf(location.getY()));

    Random random = new Random();
    int randomX = random.nextInt(x / 2);
    int randomY = random.nextInt(y / 2);

    diagonalMove(randomX, randomY);
  }

  /**
   * 对角线移动
   *
   * @param destX x
   * @param destY y
   */
  private static void diagonalMove(int destX, int destY) {

    Point location = MouseInfo.getPointerInfo().getLocation();
    int startX = Integer.parseInt(String.valueOf(location.getX()));
    int startY = Integer.parseInt(String.valueOf(location.getY()));

    destX += startX;
    destY += startY;

  }

  public static void mouseEnter(int event) throws Exception {

    TimeUnit.MILLISECONDS.sleep(DelayUtil.getStartRandomDelayTime());
    robotTool.mousePress(event);
    TimeUnit.MILLISECONDS.sleep(DelayUtil.getEndRandomDelayTime());
    robotTool.mouseRelease(event);
  }

  public static void keyEnter(int event) throws Exception {
    robotTool.keyPress(event);
    TimeUnit.MILLISECONDS.sleep(80);
    robotTool.keyRelease(event);
  }

  public static void move(String[] westCoastPosition, Point location) throws Exception {

    int[] west = {(int) (Integer.parseInt(westCoastPosition[0]) + location.getX()), (int) (Integer.parseInt(westCoastPosition[1]) + location.getY())};
    move(west);
  }

  public static void move(int[] westCoastPosition) throws Exception {
    TimeUnit.MILLISECONDS.sleep(DelayUtil.getMouseMoveDelayTime());
    robotTool.mouseMove(westCoastPosition[0], westCoastPosition[1]);
  }

  public static void keyEnter(int event, int delay) throws Exception {
    TimeUnit.MILLISECONDS.sleep(DelayUtil.getStartRandomDelayTime());
    robotTool.keyPress(event);
    TimeUnit.MILLISECONDS.sleep(delay);
    robotTool.keyRelease(event);
  }

  public static void moveMouse(int[] startPosition, int[] targetPosition, int type) throws Exception {
    java.awt.Point coordinates = pointerInfo.getLocation();

    int x = (int) coordinates.getX();
    int y = (int) coordinates.getY();

    // TODO 需要根据当前鼠标所在位置移动

    if (type == STRAIGHT_LINE) {
      int start, end;

      if (startPosition[0] == targetPosition[0]) {
        start = startPosition[1];
        end = targetPosition[1];
      } else {
        start = startPosition[0];
        end = targetPosition[0];
      }

      if (start > end) {
        for (int i = start; i >= end; i--) {
          TimeUnit.MILLISECONDS.sleep(DelayUtil.getStartRandomDelayTime(10, 10));
          robotTool.mouseMove(startPosition[0], i);
        }
      } else {
        for (int i = start; i <= end; i++) {
          TimeUnit.MILLISECONDS.sleep(DelayUtil.getStartRandomDelayTime(10, 10));
          robotTool.mouseMove(startPosition[0], i);
        }
      }
    }
  }

  /**
   * 移动到副本选择界面
   *
   * @param duplicateInfo    副本信息
   * @param keyboardPosition 移动到副本需要往哪个方向走
   */
  public static void moveToDuplicate(Robot robot, Point location, DuplicateEnum duplicateInfo, int keyboardPosition) throws Exception {

    TimeUnit.MILLISECONDS.sleep(DelayUtil.getStartRandomDelayTime(50, 10));
    robotTool.keyPress(keyboardPosition);
    String[] duplicateColors = duplicateInfo.getColor().split("-");
    String[] duplicatePosition = duplicateInfo.getPosition().split("-");
    Color curColor = robotTool.getPixelColor((int) location.getX() + Integer.parseInt(duplicatePosition[0]), (int) location.getY() + Integer.parseInt(duplicatePosition[1]));
    int x = (int) location.getX() + Integer.parseInt(duplicatePosition[0]);
    int y = (int) location.getY() + Integer.parseInt(duplicatePosition[1]);
    robotTool.mouseMove(x, y);

    while (true) {
      if (Integer.parseInt(duplicateColors[0]) == curColor.getRed()
              && Integer.parseInt(duplicateColors[1]) == curColor.getGreen()
              && Integer.parseInt(duplicateColors[2]) == curColor.getBlue()) {
        break;
      }
      curColor = robotTool.getPixelColor(x, y);
    }
    robotTool.keyRelease(keyboardPosition);
    System.out.println("准备进入副本...............");
    // TODO 需要优化
    TimeUnit.MILLISECONDS.sleep(DelayUtil.getStartRandomDelayTime(50, 10));
    robotTool.mouseMove(x, y);

    // 进入副本
    mouseEnter(InputEvent.BUTTON1_DOWN_MASK);
  }

  public static void doubleClick(int keyboard) throws Exception {

    TimeUnit.MILLISECONDS.sleep(80);
    robotTool.keyPress(keyboard);
    TimeUnit.MILLISECONDS.sleep(30);
    robotTool.keyRelease(keyboard);
    TimeUnit.MILLISECONDS.sleep(80);
    robotTool.keyPress(keyboard);
  }

  public static void keyPress(int keyboard) throws Exception {
    TimeUnit.MILLISECONDS.sleep(DelayUtil.getStartRandomDelayTime(40, 10));
    robotTool.keyPress(keyboard);
  }

  public static void keyReleased(int keyboard) throws Exception {
    TimeUnit.MILLISECONDS.sleep(40);
    robotTool.keyRelease(keyboard);
  }

  public static void keyReleased(Map<String, Integer> skillContainers) throws Exception {
    TimeUnit.MILLISECONDS.sleep(40);
    robotTool.keyRelease(KeyEvent.VK_DOWN);
    TimeUnit.MILLISECONDS.sleep(40);
    robotTool.keyRelease(KeyEvent.VK_UP);
    TimeUnit.MILLISECONDS.sleep(40);
    robotTool.keyRelease(KeyEvent.VK_LEFT);
    TimeUnit.MILLISECONDS.sleep(40);
    robotTool.keyRelease(KeyEvent.VK_RIGHT);

    if (skillContainers != null) {
      skillContainers.put("xStatus", CommonConstants.RELEASED);
      skillContainers.put("yStatus", CommonConstants.RELEASED);
    }
  }

  public static void keyReleased(int[] keyboards, int count) throws Exception {
    for (int i = 0; i < count; i++) {
      TimeUnit.MILLISECONDS.sleep(20);
      robotTool.keyRelease(keyboards[i]);
    }
  }
}
